package com.tanglongan.concurrent.monitor;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class Cache<K, V> {

    final Map<K, V> m = new HashMap<>();
    final ReadWriteLock rwl = new ReentrantReadWriteLock();
    final Lock r = rwl.readLock();  //读锁
    final Lock w = rwl.writeLock(); //写锁
    
    //写缓存
    V put(K key, V value) {
        w.lock();
        try {
            return m.put(key, value);
        } finally {
            w.unlock();
        }
    }

    //读缓存
    V get(K key) {
        V v = null;
        //读缓存
        r.lock();
        try {
            v = m.get(key);
        } finally {
            r.unlock();
        }

        if (v != null) {
            return v;
        }

        w.lock();
        try {
            //再次验证，因为其他线程可能已经查询过数据库，避免重复查询数据库
            v = m.get(key);
            if (v == null) {
                v = (V) new Object(); //此处模拟从数据库查询出结果
                m.put(key, v);
            }
        } finally {
            w.unlock();
        }
        return v;
    }

}
